#include "utils/thread_pool.h"
#include <stdexcept>
#include <memory>
#include <iostream>

// 构造函数：初始化线程池并启动指定数量的线程
// maxQueueSize为0表示无限制
ThreadPool::ThreadPool(size_t numThreads, size_t maxQueueSize) :
    stop(false),    // 停止标志（原子变量）
    activeTasks(0), // 当前执行中的任务数（原子变量）
    maxQueueSize(maxQueueSize) {

	if (numThreads == 0) {
		throw std::invalid_argument("Number of threads cannot be 0");
	}

	// 创建工作线程：每个线程运行workerThread函数
	threads.reserve(numThreads);
	for (size_t i = 0; i < numThreads; ++i) {
		threads.emplace_back(&ThreadPool::workerThread, this);
	}
}

// 查询线程池中线程的数量
size_t ThreadPool::size() const { return threads.size(); }

// 查询当前正在执行的任务数量（原子操作，无需加锁）
size_t ThreadPool::activeCount() const { return activeTasks.load(); }

// 查询等待中的任务数量（需要加锁保护队列）
size_t ThreadPool::pendingCount() const {
	std::unique_lock<std::mutex> lock(queue_mutex);
	return tasks.size();
}

// 阻塞等待所有任务完成（包括队列中的和正在执行的）
void ThreadPool::waitAll() {
	std::unique_lock<std::mutex> lock(queue_mutex);
	// 等待条件：队列空 + 无活动任务
	all_completed.wait(lock, [this] { return tasks.empty() && activeTasks.load() == 0; });
}

// 析构函数：安全关闭线程池（唤醒所有线程并等待退出）
ThreadPool::~ThreadPool() {
	// 1. 设置停止标志（锁内操作，确保同步）
	{
		std::unique_lock<std::mutex> lock(queue_mutex);
		stop = true;
	}

	// 2. 唤醒所有等待的线程（队列非空 + 队列未满的条件变量都要通知）
	queue_not_empty.notify_all();
	queue_not_full.notify_all();

	// 3. 等待所有工作线程退出
	for (std::thread &worker: threads) {
		if (worker.joinable()) {
			worker.join();
		}
	}
}

// 工作线程的核心逻辑
void ThreadPool::workerThread() {
	while (true) {
		std::function<void()> task;
		{
			std::unique_lock<std::mutex> lock(queue_mutex);

			// 等待条件：队列非空 或 线程池停止（避免虚假唤醒）
			queue_not_empty.wait(lock, [this] { return stop || !tasks.empty(); });

			// 线程池已停止且队列空，线程退出
			if (stop && tasks.empty()) {
				return;
			}

			// 取出任务（移动语义，减少拷贝）
			task = std::move(tasks.front());
			tasks.pop();
		}

		// --- 任务执行阶段（无锁） ---
		++activeTasks; // 原子递增：当前任务开始执行

		try {
			task(); // 执行任务
		} catch (const std::exception &e) {
			// 捕获标准异常，打印错误信息（避免静默失败）
			std::cerr << "[Thread Pool] Task execution exception: " << e.what() << std::endl;
		} catch (...) {
			// 捕获未知异常，打印提示
			std::cerr << "[Thread Pool] Task execution unknown exception" << std::endl;
		}

		--activeTasks; // 原子递减：当前任务执行完成
		// --- 检查是否所有任务完成 ---
		{
			std::unique_lock<std::mutex> lock(queue_mutex);
			// 条件：队列空 + 无活动任务 → 通知waitAll
			if (tasks.empty() && activeTasks.load() == 0) {
				all_completed.notify_all();
			}
		}
	}
}
